/*
 * REFAutoReleasePool.h
 *
 *  Created on: Jan 23, 2013
 *      Author: Lucifer
 */

#ifndef	__BFX_REFOBJECTPOOL_H__
#define	__BFX_REFOBJECTPOOL_H__

namespace BFX
{

//////////////////////////////////////////////////////////////////////////////
// An auto-release pool stores objects that are release them when the pool itself is drained.

class BFX_API REFAutoreleasePool : virtual public REFObject
{
private:
	// uses hash-storage for performance.
	struct Entry : public REFObject
	{
		REF<REFObject>	m_pObject;
		int				m_nHashCode;
		REF<Entry>		m_pNext;
	};

public:
	REFAutoreleasePool();
	virtual ~REFAutoreleasePool();

	// Adds a given object to the active auto-release pool in the current thread.
	static void AddObject(const REFObject *pObject);
	// Releases and pops all objects in the active auto-release pool.
	static void Drain();

	// Cleanup static resources.
	// But actually, no necessary to call this method manually.
	static void StaticFinalize();

	// Get current autorelease pool, or create new pool if not exists (with 0 refcount).
	static REFAutoreleasePool* CreateOrGetCurrentPool();

private:
	static void StaticInitialize();

	void Add(const REFObject *pObject);
	void Remove(const REFObject *pObject);
	void Clear();

	// This method has been overridden, and should never be called.
	virtual void Autorelease() const { BFX_ASSERT(false); }

private:
	static SpinLock	s_initLock;
	static bool		s_bInitialized;
	static HANDLE	s_hTlsSlot;

	REFAutoreleasePool*	m_pPoolPrev;
	int m_nSize;
	REF<Entry>*	m_pBuckets;
};

} /* namespace BFX */

#endif	//	__BFX_REFOBJECTPOOL_H__
